
#include"bsp_ALS.h"
#include"ALS_Config.h"

#define ALS_DEBUG 0
#define ALS_INT_PORT (P2ID & BIT4)

uint16 usProx_Data;
float  fALS_Data;

static void ALS_Dealyms(uint8 _time)
{
    delay_ms(_time);
}

/****************************************************************************************
* 函数名称：Init_ALS
* 入口参数：void
* 返回值： none
* 功能描述：初始化数字接近和环境光传感器 - APDS-9930
* Note：
****************************************************************************************/
uint8 ALS_ID = 0;
uint16 Prx_data=0;
void Init_ALS(void)
{

    HW_IIC_init();

    ALS_ID = ALS_RD_REG(REG_DEV_ID);
    if(ALS_ID != APDS9930_ADDR)
    {
        //没接传感器 或者 传感器有问题
        CLRWDT(); 
        while(1);
    }

    ALS_Init_BasicReg();
    ALS_ClearALL_ISR();
    ALS_Dealyms(12);
    
    #if ALS_DEBUG

    while(1)
    {
        ALS_Read_Proximity(&Prx_data);
        ALS_Read_Lux(&fALS_Data);
        ALS_Dealyms(20);

        if( 0 == ALS_INT_PORT )
        {
            ALS_Dealyms(1);
            ALS_RD_REG(REG_DEV_STA);
            ALS_ClearALL_ISR( );
        }
    }
    #endif

}

/****************************************************************************************
* 函数名称：Init_ALS_ISR
* 入口参数：void
* 返回值： none
* 功能描述：初始化MCU中断及Sensor上下限配置
* Note：
****************************************************************************************/
void ALS_Init_ISR(void)
{
    /*
        P2.4
        Disable Output
        &
        enable input
    */
    P2OE |= BIT4;
    P2IE |= BIT4;
    P24FS = 0x00;
}

/****************************************************************************************
* 函数名称：Init_ALS_BasicReg_Init
* 入口参数：void
* 返回值： none
* 功能描述：基本寄存器初始化
* Note：
****************************************************************************************/
void ALS_Init_BasicReg(void)
{
    // 配置ADC采样时间
    ALS_WR_REG(REG_ALS_TIME, DEFAULT_ATIME);    //2.73 ms 1 cycles  Max Count:1023
    ALS_WR_REG(REG_PROX_TIME,DEFAULT_PTIME);    // recommended 0xFF
    ALS_WR_REG(REG_WAIT_TIME,DEFAULT_WTIME);
    ALS_WR_REG(REG_PROX_PULSE,DEFAULT_PPULSE);
    ALS_WR_REG(REG_PROX_OFFSET,DEFAULT_POFFSET);
    ALS_WR_REG(REG_CONFIG,DEFAULT_CONFIG);

    // ADC增益配置
    ALS_WR_REG (REG_GAIN_CTR, DEFAULT_PDRIVE | DEFAULT_PDIODE | DEFAULT_PGAIN | DEFAULT_AGAIN);


    //配置距离中断触发阈值
    ALS_Set_Proximity_Interrupt_Threshold(1,DEFAULT_PILT);//Low  Threshold
    ALS_Set_Proximity_Interrupt_Threshold(0,DEFAULT_PIHT);//High Threshold

    //使能 Proximity的中断 、等待间隔 、Lux、Power
    ALS_WR_REG (REG_ENABLE,PIEN|WEN|PEN|AEN|PON); 
    
    ALS_WR_REG(REG_ISR_PERS_FIL,DEFAULT_PERS);
}


/****************************************************************************************
* 函数名称：ALS_Read_Lux
* 入口参数：_lux 环境光强
* 返回值：
* 功能描述：读取环境光强	  
* Note：
****************************************************************************************/
void ALS_Read_Lux(float *_lux)
{
    uint16 ch0, ch1,IAC1,IAC2;
    uint8 x[4] = {1, 8, 16, 120};
    float ALSIT = 2.73f * (256 - DEFAULT_ATIME);
    float iac;
    float lpc;

    ALS_Read_Ch0Light(&ch0);
    ALS_Read_Ch1Light(&ch1);

    IAC1 = ( ch0 - (uint16)(ALS_B*ch1));
    IAC2 = ( (uint16)(ALS_C*ch0) - (uint16)(ALS_D*ch1));

    lpc = (GA * DF) / (ALSIT * x[0]);

    if(IAC1>IAC2)
    {
        iac = IAC1;
    }else{
        iac = IAC2;
    }

    if (iac < 0)
        iac = 0;

    *_lux = iac * lpc;
}



uint8 ALS_Read_Ch0Light(uint16 *_ch0)
{
    if(0 != _ch0)
    {
        uint16 reg_data=0;
        reg_data   = ALS_RD_REG(REG_CH0_DATAH);
        
        *_ch0 = (uint16_t)(reg_data<<8);
          
        reg_data = ALS_RD_REG(REG_CH0_DATAL);

        *_ch0 += reg_data;

        return 1;
    }

    return 0;

}

uint8 ALS_Read_Ch1Light(uint16 *_ch1)
{
    if(0 != _ch1)
    {
        uint16 reg_data=0;
        reg_data   = ALS_RD_REG(REG_CH1_DATAH);
        
        *_ch1 = (uint16_t)(reg_data<<8);
          
        reg_data = ALS_RD_REG(REG_CH1_DATAL);

        *_ch1 += reg_data;

        return 1;
    }

    return 0;
}


/****************************************************************************************
* 函数名称：ALS_Read_Proximity
* 入口参数：_prox_data 距离
* 返回值：	
* 功能描述：读取接近距离
* Note：
****************************************************************************************/
uint8 ALS_Read_Proximity(uint16 *_prox_data)
{
    if(0 != _prox_data)
    {
        uint16 reg_data=0;
        reg_data   = ALS_RD_REG(REG_PROX_DATAH);
        
        *_prox_data = (uint16_t)(reg_data<<8);
          
        reg_data = ALS_RD_REG(REG_PROX_DATAL);

        *_prox_data += reg_data;

        return 1;
    }

    return 0;

}


/****************************************************************************************
* 函数名称：APDS_WR_REG
* 入口参数：_address：寄存器地址 ， _dat ： 写入数据 
* 返回值：	
* 功能描述：
* Note：
****************************************************************************************/
void ALS_WR_REG(uint8 _address,uint8 _dat)
{
    IIC_Start();

    IIC_Send_Data( (APDS9930_ADDR << 1) & (0xFE) );

    IIC_Send_Data(0x80 | _address);

    IIC_Send_Data(_dat);

    IIC_Stop();
}


/****************************************************************************************
* 函数名称：APDS_WR_Byte
* 入口参数：_dat 写入命令
* 返回值： none 
* 功能描述：
* Note：
****************************************************************************************/
void ALS_WR_Byte(uint8 _dat)
{
    IIC_Start();

    IIC_Send_Data( (APDS9930_ADDR << 1) & (0xFE) );

    IIC_Send_Data(_dat);

    IIC_Stop();

}

/****************************************************************************************
* 函数名称：APDS_RD_REG
* 入口参数：
		_address：寄存器地址
* 返回值：	
* 功能描述：读寄存器
* Note：
****************************************************************************************/
uint8 ALS_RD_REG(uint8 _address)
{
    uint8 recv_data;

    IIC_Start();

    IIC_Send_Data((APDS9930_ADDR << 1) & (0xFE));
    
    IIC_Send_Data(0xA0 | _address);

    IIC_ReStart();
    
    IIC_Send_Data((APDS9930_ADDR << 1) | (0x01));
    
    IIC_Read_Data(&recv_data,1);
    
    IIC_Stop();

    return (uint8)recv_data;
}


/****************************************************************************************
* 函数名称：HW_IIC_init
* 入口参数：none
* 返回值： none 
* 功能描述： 初始化硬件IIC接口，速度为100kb/s
* Note：
    P9.1 SDA
    P9.2 SCL
****************************************************************************************/
void HW_IIC_init(void)
{
    P9FS &= ~(BIT1|BIT2);
    // 0:允许输出 1 禁止输出
    P9OE &= ~(BIT1|BIT2);
    // 0:允许输入 1 禁止输入
    P9IE &= ~(BIT1|BIT2);
    //释放 SCL SDA 
    P9OD |= (BIT1|BIT2);

    ALS_Init_ISR();
    
    PRCtrl0 |= BIT6;
    SITHH = 0x00;
    SITHL = 100;
    
    IIC_Init(1,0);
}


/****************************************************************************************
* 函数名称：ALS_Set_Proximity_Interrupt_Threshold
* 入口参数：
        _islow：是否是下限，否则为上限 
        threshold：阈值
* 返回值： none 
* 功能描述： 设置距离触发中断上/下限
* Note：
****************************************************************************************/
void ALS_Set_Proximity_Interrupt_Threshold(uint8 _islow,uint16 threshold)
{
    uint8 threshold_h,threshold_l;
    threshold_h = (uint8)(threshold >>   8);
    threshold_l = (uint8)(threshold & 0xFF);

    if(0 == _islow){

        //配置触发上限，实际最近的距离
        ALS_WR_REG(REG_PROX_ISRHI_H,threshold_h);
        ALS_WR_REG(REG_PROX_ISRHI_L,threshold_l);

    }else if(1 == _islow){

        //配置触发下限，实际最远的距离
        ALS_WR_REG(REG_PROX_ISRLO_H,threshold_h);
        ALS_WR_REG(REG_PROX_ISRLO_L,threshold_l);

    }
}

/****************************************************************************************
* 函数名称：ALS_Set_ALS_Interrupt_Threshold
* 入口参数：
        _islow：是否是下限，否则为上限 
        threshold：阈值
* 返回值： none 
* 功能描述： 设置环境光触发中断上/下限
* Note：
****************************************************************************************/
void ALS_Set_ALS_Interrupt_Threshold(uint8 _islow,uint16 threshold)
{
    uint8 threshold_h,threshold_l;
    threshold_h = (uint8)(threshold >>   8);
    threshold_l = (uint8)(threshold & 0xFF);

    if(0 == _islow){

        //配置触发上限
        ALS_WR_REG(REG_ALS_ISRHI_H,threshold_h);
        ALS_WR_REG(REG_ALS_ISRHI_L,threshold_l);

    }else if(1 == _islow){

        //配置触发下限
        ALS_WR_REG(REG_ALS_ISRLO_H,threshold_h);
        ALS_WR_REG(REG_ALS_ISRLO_L,threshold_l);

    }
}

/****************************************************************************************
* 函数名称：ALS_ClearALL_ISR
* 入口参数：none
* 返回值： none 
* 功能描述： 清除 Proximity & ALS 引起的中断
* Note：
    INT引脚，如果不清除的话，会一直保持低电平
****************************************************************************************/
void ALS_ClearALL_ISR(void)
{
    ALS_WR_Byte(0xE7);
}


/****************************************************************************************
* 函数名称：ALS_PowerDown
* 入口参数：none
* 返回值： none 
* 功能描述： ALS 进入Sleep状态
* Note：
****************************************************************************************/
void ALS_PowerDown(void)
{
    /*
        PON:"BIT0"
    */
    uint8 reg_dat;
    reg_dat  = ALS_RD_REG(REG_ENABLE);
    reg_dat &= ~BIT0;
    ALS_WR_REG(REG_ENABLE,reg_dat);

}


/****************************************************************************************
* 函数名称：ALS_PowerOn
* 入口参数：none
* 返回值： none 
* 功能描述： 唤醒ALS，进入测量状态
* Note：
****************************************************************************************/
void ALS_PowerOn(void)
{
    /*
        PON:"BIT0"
    */
    uint8 reg_dat;
    reg_dat  = ALS_RD_REG(REG_ENABLE);
    reg_dat |= BIT0;
    ALS_WR_REG(REG_ENABLE,reg_dat);
}

